﻿using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace Nirvana
{
    [CustomEditor(typeof(QualityConfig))]
    public class QualityConfigEditor : Editor
    {
        private QualityConfig qualityConfig;
        private SerializedProperty levels;
        private ReorderableList levelList;

        public override void OnInspectorGUI()
        {
            if (this.qualityConfig == null)
            {
                var qualityConfigs = QualityConfig.FindConfigs();
                if (qualityConfigs.Length == 0)
                {
                    EditorGUILayout.HelpBox("There has no quality config in the project.", MessageType.Error);
                    this.qualityConfig = null;
                }
                else
                {
                    if (qualityConfigs.Length > 1)
                    {
                        EditorGUILayout.HelpBox("There are more than one quality config.", MessageType.Warning);
                    }
                    this.qualityConfig = qualityConfigs[0];
                }
            }

            if (this.qualityConfig != null)
            {
                var levelCount = this.qualityConfig.GetLevelCount();
                var qualityMenu = new string[levelCount];
                for (int i = 0; i < levelCount; ++i)
                {
                    var level = this.qualityConfig.GetLevel(i);
                    qualityMenu[i] = level.Name;
                }

                //var currentLevel = QualityConfig.QualityLevel;
                //EditorGUI.BeginChangeCheck();
                //currentLevel = EditorGUILayout.Popup("Current Quality:", currentLevel, qualityMenu);
                //if (EditorGUI.EndChangeCheck())
                //{
                //    QualityConfig.QualityLevel = currentLevel;
                //}

                EditorGUILayout.Space();
            }

            //Draw the editor.
            this.serializedObject.Update();

            GUILayout.Label("QualitySettings", GUITheme.LabelTitleStyle);
            EditorGUILayout.Space();

            EditorGUILayout.HelpBox("品质配置表，根据不同性能设备，设置不同品质环境参数。\n", MessageType.None);
            EditorGUILayout.Space();

            this.levelList.DoLayoutList();
            EditorGUILayout.Space();

            if (this.levelList.index != -1 && this.levels.arraySize > 0)
            {
                var selected = this.levels.GetArrayElementAtIndex(this.levelList.index);
                if (selected != null)
                {
                    GUILayoutEx.BeginContents();
                    this.OnDrawQualityLevel(selected);
                    GUILayoutEx.EndContents();

                    if (GUILayoutEx.ActionButton("Active"))
                    {
                        var config = (QualityConfig)this.target;

                        if (this.levelList.index == -1)
                        {
                            Debug.LogError("please select quality");
                            return;
                        }
                        else
                        {
                            var level = config.GetLevel(this.levelList.index);
                            if (level != null)
                            {
                                level.Active();
                            }
                        }
                    }
                }
            }

            this.serializedObject.ApplyModifiedProperties();

        }


        private void OnEnable()
        {
            if (target == null)
            {
                return;
            }

            levels = serializedObject.FindProperty("levels");
            levelList = new ReorderableList(serializedObject, levels);
            levelList.drawHeaderCallback = rect => GUI.Label(rect, "QualityConfit List:");
            levelList.elementHeight = EditorGUIUtility.singleLineHeight;
            levelList.drawElementCallback = (rect, index, isActive, isFocused) =>
            {
                var element = levels.GetArrayElementAtIndex(index);
                GUI.Label(rect, element.displayName);
            };
        }

        private void OnDrawQualityLevel(SerializedProperty property)
        {
            EditorGUILayout.Space();
            GUI.color = Color.yellow;
            GUILayout.Label("Quality Level Name", EditorStyles.boldLabel);
            GUI.color = Color.white;
            var name = property.FindPropertyRelative("name");
            EditorGUILayout.PropertyField(name);
            EditorGUILayout.Space();
            GUI.color = Color.yellow;
            GUILayout.Label("Rendering", EditorStyles.boldLabel);
            GUI.color = Color.white;
            this.OnDrawQualityRendering(property);
            EditorGUILayout.Space();

            GUI.color = Color.yellow;
            GUILayout.Label("Shadows", EditorStyles.boldLabel);
            GUI.color = Color.white;
            this.OnDrawQualityShadows(property);
            EditorGUILayout.Space();

            GUI.color = Color.yellow;
            GUILayout.Label("Others", EditorStyles.boldLabel);
            GUI.color = Color.white;
            this.OnDrawQualityOthers(property);
            EditorGUILayout.Space();
        }
        private void OnDrawQualityRendering(SerializedProperty property)
        {
            var pixelLightCount = property.FindPropertyRelative("pixelLightCount");
            var masterTextureLimit = property.FindPropertyRelative("textureQuality");
            var anisotropicFiltering = property.FindPropertyRelative("anisotropicTextures");
            var antiAliasing = property.FindPropertyRelative("antiAliasing");
            var softParticles = property.FindPropertyRelative("softParticles");
            var softVegetation = property.FindPropertyRelative("softVegetation");
            var realtimeReflectionProbes = property.FindPropertyRelative("realtimeReflectionProbes");
            var billboardsFaceCameraPosition = property.FindPropertyRelative("billboardsFaceCameraPosition");

            EditorGUILayout.PropertyField(pixelLightCount);
            EditorGUILayout.PropertyField(masterTextureLimit);
            EditorGUILayout.PropertyField(anisotropicFiltering);
            EditorGUILayout.PropertyField(antiAliasing);
            EditorGUILayout.PropertyField(softParticles);
            if (softParticles.boolValue)
            {
                this.SoftParticlesHintGUI();
            }

            EditorGUILayout.PropertyField(softVegetation);
            EditorGUILayout.PropertyField(realtimeReflectionProbes);
            EditorGUILayout.PropertyField(billboardsFaceCameraPosition);
        }

        private void OnDrawQualityShadows(SerializedProperty property)
        {
            var shadowmaskMode = property.FindPropertyRelative("shadowmaskMode");
            var shadows = property.FindPropertyRelative("shadows");
            var shadowResolution = property.FindPropertyRelative("shadowResolution");
            var shadowProjection = property.FindPropertyRelative("shadowProjection");
            var shadowDistance = property.FindPropertyRelative("shadowDistance");
            var shadowNearPlaneOffset = property.FindPropertyRelative("shadowNearPlaneOffset");
            var shadowCascades = property.FindPropertyRelative("shadowCascades");
            var shadowCascade2Split = property.FindPropertyRelative("shadowCascade2Split");
            var shadowCascade4Split = property.FindPropertyRelative("shadowCascade4Split");

            EditorGUILayout.PropertyField(shadowmaskMode);
            EditorGUILayout.PropertyField(shadows);
            if (shadows.enumValueIndex != (int)ShadowQuality.Disable)
            {
                EditorGUILayout.PropertyField(shadowResolution);
                EditorGUILayout.PropertyField(shadowProjection);
                EditorGUILayout.PropertyField(shadowDistance);
                EditorGUILayout.PropertyField(shadowNearPlaneOffset);
                EditorGUILayout.PropertyField(shadowCascades);
                if (shadowCascades.intValue == 2)
                {
                    EditorGUILayout.PropertyField(shadowCascade2Split);
                }
                else if (shadowCascades.intValue == 4)
                {
                    EditorGUILayout.PropertyField(shadowCascade4Split);
                }
            }
        }

        private void OnDrawQualityOthers(SerializedProperty property)
        {
            var blendWeights = property.FindPropertyRelative("blendWeights");
            var vSyncCount = property.FindPropertyRelative("vSyncCount");
            var lodBias = property.FindPropertyRelative("lodBias");
            var maximumLODLevel = property.FindPropertyRelative("maximumLODLevel");
            var particleRaycastBudget = property.FindPropertyRelative("particleRaycastBudget");
            var maxQueuedFrames = property.FindPropertyRelative("maxQueuedFrames");
            var asyncUploadTimeSlice = property.FindPropertyRelative("asyncUploadTimeSlice");
            var asyncUploadBufferSize = property.FindPropertyRelative("asyncUploadBufferSize");
            var setResolution = property.FindPropertyRelative("setResolution");
            var resulutionWidth = property.FindPropertyRelative("resulutionWidth");
            var resulutionHeight = property.FindPropertyRelative("resulutionHeight");
            var frameRate = property.FindPropertyRelative("frameRate");
            var sleepTimeout = property.FindPropertyRelative("sleepTimeout");

            EditorGUILayout.PropertyField(blendWeights);
            EditorGUILayout.PropertyField(vSyncCount);
            EditorGUILayout.PropertyField(lodBias);
            EditorGUILayout.PropertyField(maximumLODLevel);
            EditorGUILayout.PropertyField(particleRaycastBudget);
            EditorGUILayout.PropertyField(maxQueuedFrames);
            EditorGUILayout.PropertyField(asyncUploadTimeSlice);
            EditorGUILayout.PropertyField(asyncUploadBufferSize);
            EditorGUILayout.PropertyField(setResolution);
            if (setResolution.boolValue)
            {
                EditorGUILayout.PropertyField(resulutionWidth);
                EditorGUILayout.PropertyField(resulutionHeight);
            }

            EditorGUILayout.PropertyField(frameRate);
            EditorGUILayout.PropertyField(sleepTimeout);
        }

        private void SoftParticlesHintGUI()
        {
            Camera main = Camera.main;
            if (main != null)
            {
                var actualRenderingPath = main.actualRenderingPath;
                if (actualRenderingPath != RenderingPath.DeferredLighting &&
                    actualRenderingPath != RenderingPath.DeferredShading)
                {
                    if ((main.depthTextureMode & DepthTextureMode.Depth) == DepthTextureMode.None)
                    {
                        EditorGUILayout.HelpBox("Soft Particles require using Deferred Lighting or making camera render the depth texture.",
                            MessageType.Warning,
                            false);
                    }
                }
            }
        }
    }
}

